package io;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

import config.Config;

public class FileNetReceiverIO {

	public static void main(String[] args) throws IOException {
		ServerSocket serverSocket = null;
		Socket clientSocket = null;

		try {
			serverSocket = new ServerSocket(Config.NET_SERVER_PORT,
					Config.NET_BACKLOG, InetAddress.getByName(Config.NET_SERVER_IP));
			System.out.println("Waiting for connection...");

			while (clientSocket == null) {
				try {
					clientSocket = serverSocket.accept();
				} catch (IOException e) {
					System.err
							.println("Accept failed. Waiting for connection...");
				}
			}

			System.out.printf(
					"Connection successful. Server IP: %s. Client IP: %s.\n",
					serverSocket.getInetAddress().toString(), clientSocket
							.getInetAddress().toString());
			System.out.println("Waiting for input...");

			try (InputStream socketIn = clientSocket.getInputStream();
					DataOutputStream dos = new DataOutputStream(
							new FileOutputStream(new File(
									Config.OUTPUT_FILE_NET_IO)));
					OutputStream socketOut = clientSocket.getOutputStream();) {

				byte[] buf = new byte[Config.NET_BUF_SIZE];

				int size = Integer.MAX_VALUE;

				int totalRcvdBytes = 0;

				while (size > 0 && totalRcvdBytes < Config.FILE_SIZE_BYTES) {
					size = socketIn.read(buf);
					totalRcvdBytes += size;
					if (size > 0) {
						dos.write(buf, 0, size);
						if (totalRcvdBytes == size) {
							System.out
									.printf("First %d bytes received. Receiving more data...\n",
											size);
						}
					}
				}

				socketOut.write(Config.TX_ACK_BYTE);
				System.out.println("All data is received. TX ack sent.");
			}

		} catch (IOException e) {
			System.err.printf("Could not listen on port %d. Details: %s.\n",
					Config.NET_SERVER_PORT, e.getMessage());
		} finally {
			if (serverSocket != null) {
				serverSocket.close();
			}
			if (clientSocket != null) {
				clientSocket.close();
			}
		}
	}
}
